package com.ruoyi.SSL.controller;

import java.util.ArrayList;
import java.util.List;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ruoyi.SSL.domain.SslApply;
import com.ruoyi.SSL.domain.SslTrusteeshipService;
import com.ruoyi.SSL.domain.SslTrusteeshipServiceDomain;
import com.ruoyi.SSL.service.ISslApplyService;
import com.ruoyi.SSL.service.ISslTrusteeshipServiceService;
import com.ruoyi.common.config.ServerConfig;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.utils.CacheUtils;
import com.ruoyi.common.utils.CommUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysConfigService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.SSL.domain.SslDomain;
import com.ruoyi.SSL.service.ISslDomainService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 证书域名管理Controller
 *
 * @author ruoyi
 * @date 2024-10-12
 */
@Controller
@RequestMapping("/SSL/domain1")
public class SslDomainController extends BaseController
{
    private String prefix = "SSL/domain1";

    @Autowired
    private ISslDomainService sslDomainService;

    @Autowired
    private ISysConfigService configService;
    @Autowired
    private ISslTrusteeshipServiceService trusteeshipServiceService;
    @Autowired
    private ISslApplyService applyService;

    @RequiresPermissions("SSL:domain:view")
    @GetMapping()
    public String domain(String serId, ModelMap modelMap)
    {
        modelMap.put("serId", serId);
        return prefix + "/domain";
    }

    /**
     * 查询证书域名管理列表
     */
    @RequiresPermissions("SSL:domain:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(SslDomain sslDomain)
    {
        startPage();
        List<SslDomain> list = sslDomainService.selectSslDomainList(sslDomain);
        return getDataTable(list);
    }

    @ResponseBody
    @PostMapping("/deployDomainList")
    public AjaxResult deployDomainList(SslDomain sslDomain){
        if(sslDomain.getIsUniversal().equals("Y")){
            String domainRoot = "";
            AjaxResult aj = applyService.isHaveSpecialDomain(sslDomain.getCertificateDomain());
            if(aj.isSuccess()){
                domainRoot = String.valueOf(aj.get("data"));
            }else{
                String domainTmp = sslDomain.getCertificateDomain().substring(0, sslDomain.getCertificateDomain().lastIndexOf("."));
                String domainSuffix = sslDomain.getCertificateDomain().substring(sslDomain.getCertificateDomain().lastIndexOf("."));
                domainRoot = domainTmp.contains(".")?domainTmp.split("\\.")[domainTmp.split("\\.").length-1]+domainSuffix:domainTmp+domainSuffix;
            }
            String domainTmp = sslDomain.getCertificateDomain().replace(domainRoot, "");
            String queryDomainText = sslDomain.getCertificateDomain();
            if(StrUtil.isNotBlank(domainTmp)){
                if(domainTmp.split("\\.").length > 1){
                    queryDomainText = "*."+domainTmp.substring(domainTmp.indexOf(".")+1)+domainRoot;
                }else{
                    queryDomainText = "*."+domainRoot;
                }
            }
            sslDomain.setCertificateDomain(queryDomainText);
            List<SslDomain> domainList = sslDomainService.selectSslDomainList(sslDomain);
            if(domainList != null && domainList.size() > 0 ){
                return AjaxResult.success("", domainList.get(0));
            }else{
                return AjaxResult.success("", queryDomainText);
            }
        }else{
            List<SslDomain> domainList = sslDomainService.selectSslDomainList(sslDomain);
            if(domainList != null && domainList.size() > 0 ){
                return AjaxResult.success("", domainList.get(0));
            }else{
                return AjaxResult.success("", sslDomain.getCertificateDomain());
            }
        }
    }

    /**
     * 导出证书域名管理列表
     */
    @RequiresPermissions("SSL:domain:export")
    @Log(title = "证书域名管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(SslDomain sslDomain)
    {
        List<SslDomain> list = sslDomainService.selectSslDomainList(sslDomain);
        ExcelUtil<SslDomain> util = new ExcelUtil<SslDomain>(SslDomain.class);
        return util.exportExcel(list, "证书域名管理数据");
    }

    /**
     * 新增证书域名管理
     */
    @GetMapping("/add")
    public String add(ModelMap modelMap)
    {
        //判断是否已经配置了请求appId和秘钥
        String appId = configService.selectConfigByKey("api.appId");
        String appSecret = configService.selectConfigByKey("api.appSecret");
        if(StringUtils.isBlank(appId) || StringUtils.isBlank(appSecret)){
            throw new RuntimeException("平台公用参数配置有误！");
        }
        AjaxResult aj = configService.getPlatformInfoByAppId(CommUtils.REQ_API_URI, appId, appSecret);
        if(aj.isSuccess()){
            modelMap.put("platFormInfo", JSONUtil.parseObj(aj.get("data")));
        }else{
            modelMap.put("platFormInfo", null);
            modelMap.put("error", aj.get("msg").toString());
        }
        return prefix + "/add";
    }

    /**
     * 用来判断渔民格式及生成出验证信息
     * @param domainName 需要判断的域名
     */
    @ResponseBody
    @GetMapping("/applyBefore")
    public AjaxResult applyBefore(String domainName){
       return sslDomainService.applyBefor(domainName);
    }

    /**
     * 验证域名的解析是否已经添加了
     * @param domainName 需要判断的域名
     */
    @ResponseBody
    @GetMapping("/verifyDNSExist")
    public AjaxResult verifyDNSExist(String domainName, String rrVal){
        return CommUtils.isHasAuthInfo(domainName, rrVal);
        /*AjaxResult aj = CommUtils.isHasAuthInfo(domainName, rrVal);
        if(aj.isSuccess()){
            //插入数据
            SslDomain domain = new SslDomain();
            domain.setCertificateDomain(domainTxt);
            List<SslDomain> domainList = sslDomainService.selectSslDomainList(domain);
            if(domainList != null && domainList.size() > 0){
                domain = domainList.get(0);
                //判断CNAME记录值是否为空  如果为空则修改该字段值
                if(StrUtil.isBlank(domain.getRrVal())){
                    domain.setRrVal(rrVal);
                    //修改数据
                    sslDomainService.updateSslDomain(domain);
                }
            }else{
                //如果不存在的数据  则插入新的数据
                domain.setIsYzOver("Y");
                domain.setRrVal(rrVal);
                //插入数据
                sslDomainService.insertSslDomain(domain);
            }
            return AjaxResult.success();
        }
        return aj;*/
    }

    /**
     * 新增保存证书域名管理
     */
    @RequiresPermissions("SSL:domain:add")
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(SslDomain sslDomain)
    {
        SslDomain domain = new SslDomain();
        domain.setCertificateDomain(sslDomain.getCertificateDomain());
        List<SslDomain> domainList = sslDomainService.selectSslDomainList(domain);
        if(domainList != null && domainList.size() > 0 && domainList.size() < 2){
            sslDomain.setId(domainList.get(0).getId());
            sslDomain.setIsYzOver("Y");
            sslDomain.setIsAutoSsl("N");
            //保存数据
            sslDomainService.updateSslDomain(sslDomain);
            //执行申请证书的方法
            return sslDomainService.applySSL(sslDomain);
        }else{
            sslDomain.setIsYzOver("Y");
            sslDomain.setIsAutoSsl("N");
            AjaxResult aj = toAjax(sslDomainService.insertSslDomain(sslDomain));
            if(aj.isSuccess()){
                //执行申请证书的方法
                return sslDomainService.applySSL(sslDomain);
            }
            return aj;
        }
    }

    /**
     * 重新申请的方法
     */
    @ResponseBody
    @GetMapping("/retryApply/{id}")
    public AjaxResult retryApply(@PathVariable("id")long id){
        SslDomain sslDomain = sslDomainService.selectSslDomainById(id);
        if(sslDomain != null && !StrUtil.isBlankIfStr(sslDomain.getId())){
            //执行申请证书的方法
            return sslDomainService.applySSL(sslDomain);
        }
        return AjaxResult.error("错误！");
    }

    @PostMapping("/saveSetInfo")
    @ResponseBody
    public AjaxResult saveSetInfo(SslDomain sslDomain){
        SslDomain domain = new SslDomain();
        domain.setCertificateDomain(sslDomain.getCertificateDomain());
        List<SslDomain> domainList = sslDomainService.selectSslDomainList(domain);
        if(domainList != null && domainList.size() > 0 && domainList.size() < 2){
            sslDomain.setId(domainList.get(0).getId());
            sslDomain.setIsYzOver("Y");
            sslDomain.setIsAutoSsl("Y");
            //保存数据
            sslDomainService.updateSslDomain(sslDomain);
            //返回数据
            return AjaxResult.success("更新配置完成！");
        }else{
            return AjaxResult.error("域名数据错误！");
        }
    }


    @ResponseBody
    @GetMapping("/isYz/{id}")
    public AjaxResult isYz(@PathVariable("id") Long id){
        SslDomain sslDomain = sslDomainService.selectSslDomainById(id);
        //判断是否已经配置了请求appId和秘钥
        String appId = configService.selectConfigByKey("api.appId");
        String appSecret = configService.selectConfigByKey("api.appSecret");
        if(StringUtils.isBlank(appId) || StringUtils.isBlank(appSecret)){
            return AjaxResult.error("平台公用参数配置有误！");
        }
        if(StringUtils.isBlank(sslDomain.getIsYzOver()) || !sslDomain.getIsYzOver().equals("Y")){
            return AjaxResult.warn("由于第一次开启自动部署、续签，需要您验证一下域名的所有权！");
        }
        sslDomain.setIsAutoSsl("Y");
        //保存数据
        sslDomainService.updateSslDomain(sslDomain);
        return AjaxResult.success("不需要！");
    }

    /**
     * 修改证书域名管理
     */
    @RequiresPermissions("SSL:domain:edit")
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") Long id, ModelMap mmap)
    {
        SslDomain sslDomain = sslDomainService.selectSslDomainById(id);
        mmap.put("sslDomain", sslDomain);
        return prefix + "/edit";
    }

    /**
     * 修改保存证书域名管理
     */
    @RequiresPermissions("SSL:domain:edit")
    @Log(title = "证书域名管理", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(SslDomain sslDomain)
    {
        return toAjax(sslDomainService.updateSslDomain(sslDomain));
    }

    /**
     * 删除证书域名管理
     */
    @RequiresPermissions("SSL:domain:remove")
    @Log(title = "证书域名管理", businessType = BusinessType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        return toAjax(sslDomainService.deleteSslDomainByIds(ids));
    }


    @ResponseBody
    @GetMapping("/queryTree")
    public List<Ztree> queryTree()
    {
        return sslDomainService.selectTree(new SslDomain());
    }

    @ResponseBody
    @PostMapping("/enableAutoSSL")
    public AjaxResult enableAutoSSL(SslDomain sslDomain){
        return sslDomainService.firstEnableAutoSSL(sslDomain);
    }

    @GetMapping("/sedInfo/{id}")
    public String sedInfo(@PathVariable("id") Long id, ModelMap mmap){
        SslDomain sslDomain = sslDomainService.selectSslDomainById(id);
        mmap.put("sslDomain", sslDomain);
        //判断是否已经配置了请求appId和秘钥
        String appId = configService.selectConfigByKey("api.appId");
        String appSecret = configService.selectConfigByKey("api.appSecret");
        if(StringUtils.isBlank(appId) || StringUtils.isBlank(appSecret)){
            throw new RuntimeException("平台公用参数配置有误！");
        }
        AjaxResult aj = configService.getPlatformInfoByAppId(CommUtils.REQ_API_URI, appId, appSecret);
        if(aj.isSuccess()){
            mmap.put("platFormInfo", JSONUtil.parseObj(aj.get("data")));
        }else{
            mmap.put("platFormInfo", null);
            mmap.put("error", aj.get("msg").toString());
        }
        return prefix + "/sedInfo";
    }

    @GetMapping("/setTime/{id}")
    public String setTime(@PathVariable("id") Long id, ModelMap mmap){
        SslDomain sslDomain = sslDomainService.selectSslDomainById(id);
        mmap.put("sslDomain", sslDomain);
        return prefix + "/setTime";
    }

}
